﻿using System.Collections.Generic;
using FITClub.TextureMenu;
using Microsoft.Xna.Framework;

namespace FITClub.Episode1.Components
{
    /// <summary>
    /// Trida kontroluje vykresleni a interakci s menu ENDGAME
    /// </summary>
    public class EndGameScoreList
    {
        private Menu endGame;
        private GameFITClub game;

        public Label[] LabelKills { get; private set; }

        public Label[] LabelNames { get; private set; }

        public ImageItem[] PlayerImages { get; private set; }

        public ImageItem[] IconsImages { get; private set; }

        private int activePlayers;

        /// <summary>
        /// Konstruktor, alokace kontrolek
        /// </summary>
        /// <param name="game">Odkaz na probihajici hru</param>
        /// <param name="endgame">Odkaz na menu z menu managera</param>
        public EndGameScoreList(GameFITClub game, Menu endgame)
        {
            this.endGame = endgame;
            this.game = game;

            //allocate menu components
            this.LabelKills = new Label[game.MaxPlayers];
            this.LabelNames = new Label[game.MaxPlayers];
            this.PlayerImages = new ImageItem[game.MaxPlayers];

            this.IconsImages = new ImageItem[game.MaxPlayers];

            this.activePlayers = int.Parse(this.game.ListPlayerCount.SelectedValue);

            //get components from menu
            for (int i = 0; i < game.MaxPlayers; i++)
            {
                this.LabelKills[i] = MenuManager.Current.Displayables["resultLabelKillsPlayer" + (i + 1)] as Label;
                this.LabelNames[i] = MenuManager.Current.Displayables["resultLabelNamePlayer" + (i + 1)] as Label;
                this.PlayerImages[i] = MenuManager.Current.Displayables["resultsPlayer" + (i + 1)] as ImageItem;
                this.IconsImages[i] = MenuManager.Current.Displayables["resultsCup" + (i + 1)] as ImageItem;
            }
        }

        /// <summary>
        /// Inicialiazace vsech potrebnych komponent v tomto menu
        /// </summary>
        public void Initialize()
        {
            //initialize
            for (int i = 0; i < game.MaxPlayers; i++)
            {
                this.PlayerImages[i].Visible = (i < activePlayers);
                this.LabelNames[i].Visible = (i < activePlayers);
                this.LabelKills[i].Visible = (i < activePlayers);

                this.IconsImages[i].Visible = false;
            }

            //fill with data
            for (int i = 0; i < activePlayers; i++)
            {
                this.LabelKills[i].Text = string.Format("Kills : {0}\nDeaths :{1}\n", game.GameManager.Statistics[i].Kills, game.GameManager.Statistics[i].Deaths);
                this.LabelNames[i].Text = game.PlayerNames[i].Text;
                this.PlayerImages[i].Texture = game.GameManager.Statistics[i].Character.preset.Preview;
            }

            //oznac viteze
            markWinner();
        }

        /// <summary>
        /// Oznaci (zobrazenim component v menu) vsechny hrace, kteri ziskali nejvyssi skore
        /// </summary>
        private void markWinner()
        {
            //player index, value
            var playerStats = new Dictionary<int, int>();
            int maxValue = 0;
            List<int> results = new List<int>();

            if (game.GameManager.PositionFactor == PositionFactors.Kills)
            {
                //order by kills
                for (int i = 0; i < activePlayers; i++)
                {
                    if (game.GameManager.Statistics[i].Kills == maxValue)
                    {
                        results.Add(i);
                    }
                    else if (game.GameManager.Statistics[i].Kills > maxValue)
                    {
                        maxValue = game.GameManager.Statistics[i].Kills;
                        results.Clear();        //delete all players previously marked as winners
                        results.Add(i);
                    }
                }
            }
            else
            {
                //order by lives
                for (int i = 0; i < activePlayers; i++)
                {
                    if (game.GameManager.Statistics[i].Lives == maxValue)
                    {
                        results.Add(i);
                    }
                    else if (game.GameManager.Statistics[i].Lives > maxValue)
                    {
                        maxValue = game.GameManager.Statistics[i].Lives;
                        results.Clear();        //delete all players previously marked as winners
                        results.Add(i);
                    }
                }
            }

            //if time game type is selected and there is more than one possible winners, further sorting is needed
            //BE AWARE : since game type is now TIME, primary sort factor is frags, results list are now sorted by that factor
            if (game.GameManager.getGameType() == GameType.Time && results.Count > 1)
            {
                int minDeaths = int.MaxValue;
                List<int> sortedByDeaths = new List<int>();

                foreach (int index in results)
                {
                    if (game.GameManager.Statistics[index].Deaths == minDeaths)
                    {
                        sortedByDeaths.Add(index);
                    }

                    if (game.GameManager.Statistics[index].Deaths < minDeaths)
                    {
                        minDeaths = game.GameManager.Statistics[index].Deaths;
                        sortedByDeaths.Clear();        //delete all players previously marked as winners
                        sortedByDeaths.Add(index);
                    }
                }

                //sorting is now complete, update results list by newly sort list
                results = sortedByDeaths;
            }

            //make cup of players on first position visible
            foreach (int index in results)
            {
                IconsImages[index].Visible = true;
            }
        }

        public void Draw(GameTime gameTime)
        {
            this.game.SpriteBatch.Begin();
            endGame.Draw(this.game.SpriteBatch, Color.White);
            this.game.SpriteBatch.End();
        }
    }
}